using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Timers;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Serialization;

namespace ICP_MS.Plugin.iMass;

[Serializable]
public class ClientLIMS
{
	public delegate void ReceiveEvent(string data);

	private string hostIP = "39.105.142.249";

	private int port = 9090;

	private Socket listener = null;

	private static byte[] buffer;

	private int nType = 0;

	private int retries = 0;

	private int RetryInterval = 10000;

	private int Retries = 3;

	private ClientMS lims = new ClientMS();

	private static ClientLIMS _instance;

	public string filepath = Application.StartupPath + "//Config//ClientMS.xml";

	public string HostIP
	{
		get
		{
			return hostIP;
		}
		set
		{
			hostIP = value;
		}
	}

	public int Port
	{
		get
		{
			return port;
		}
		set
		{
			port = value;
		}
	}

	public int Type
	{
		get
		{
			return nType;
		}
		set
		{
			nType = value;
		}
	}

	public static ClientLIMS Instance
	{
		get
		{
			if (_instance == null)
			{
				_instance = new ClientLIMS();
			}
			return _instance;
		}
	}

	public static event ReceiveEvent Receiveevent;

	public void Init()
	{
		FromXmlString();
		lims.Init();
		ConnectToHost();
	}

	private void ConnectCallBack(IAsyncResult ar)
	{
		Socket client = ar.AsyncState as Socket;
		try
		{
			client.EndConnect(ar);
			retries = 0;
		}
		catch (SocketException)
		{
			retries++;
			if (retries > Retries)
			{
				retries = 0;
				listener.Close();
				listener.Dispose();
				Thread thread1 = new Thread((ThreadStart)delegate
				{
					ConnectToHost();
				})
				{
					IsBackground = true
				};
				thread1.Start();
				return;
			}
			for (int i = RetryInterval; i > 0; i--)
			{
				Thread.Sleep(TimeSpan.FromSeconds(1.0));
			}
			listener.Close();
			listener.Dispose();
			Thread thread0 = new Thread((ThreadStart)delegate
			{
				ConnectToHost();
			})
			{
				IsBackground = true
			};
			thread0.Start();
			return;
		}
		System.Timers.Timer timer = new System.Timers.Timer();
		timer.Interval = 5000.0;
		timer.Enabled = true;
		timer.Elapsed += delegate
		{
			if (client.Connected)
			{
				try
				{
					SetInfoMessage();
					byte[] bytes = Encoding.UTF8.GetBytes(lims.infoData);
					client.BeginSend(bytes, 0, bytes.Length, SocketFlags.None, delegate(IAsyncResult ars1)
					{
						Socket socket2 = ars1.AsyncState as Socket;
						socket2.EndSend(ars1);
					}, client);
					if (lims.data != null)
					{
						while (lims.data.Count > 0)
						{
							string s = lims.data.Dequeue();
							byte[] bytes2 = Encoding.UTF8.GetBytes(s);
							client.BeginSend(bytes2, 0, bytes2.Length, SocketFlags.None, delegate(IAsyncResult ars2)
							{
								Socket socket = ars2.AsyncState as Socket;
								socket.EndSend(ars2);
							}, client);
						}
					}
					return;
				}
				catch (SocketException ex2)
				{
					Console.WriteLine(ex2.Message);
					return;
				}
			}
			listener.Close();
			listener.Dispose();
			ConnectToHost();
			timer.Stop();
			timer.Enabled = false;
		};
		timer.Start();
		listener.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveMessage, listener);
	}

	public bool ConnectToHost()
	{
		try
		{
			listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
			listener.ReceiveTimeout = 1000;
			listener.SendTimeout = 1000;
			listener.BeginConnect(new IPEndPoint(IPAddress.Parse(HostIP), Port), ConnectCallBack, listener);
		}
		catch (Exception)
		{
			Dispose();
		}
		finally
		{
		}
		return false;
	}

	public void SetErrorMessage()
	{
		lims.SetErrorMessage();
	}

	public void SetInfoMessage()
	{
		lims.SetInfoMessage();
	}

	public void Dispose()
	{
		retries = 0;
		if (listener != null)
		{
			listener.Close();
			listener.Dispose();
		}
	}

	public static void ReceiveMessage(IAsyncResult ar)
	{
		int length = 0;
		string message = "";
		Socket socket = ar.AsyncState as Socket;
		try
		{
			length = socket.EndReceive(ar);
			message = Encoding.UTF8.GetString(buffer, 0, length);
			if (ClientLIMS.Receiveevent != null)
			{
				ClientLIMS.Receiveevent(message);
			}
			socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveMessage, socket);
		}
		catch (Exception)
		{
		}
	}

	public bool CreateXML()
	{
		XmlWriter writer = null;
		XmlWriterSettings writerSetting = new XmlWriterSettings
		{
			Indent = true,
			Encoding = Encoding.UTF8
		};
		try
		{
			if (!Directory.Exists(Application.StartupPath + "//Config"))
			{
				Directory.CreateDirectory(Application.StartupPath + "//Config");
			}
			writer = XmlWriter.Create(filepath, writerSetting);
		}
		catch (Exception)
		{
			return false;
		}
		try
		{
			XmlSerializer xser = new XmlSerializer(typeof(ClientLIMS));
			xser.Serialize(writer, Instance);
		}
		catch (Exception)
		{
			return false;
		}
		finally
		{
			writer.Close();
		}
		return true;
	}

	public bool FromXmlString()
	{
		try
		{
			string xmlString = File.ReadAllText(filepath);
			if (string.IsNullOrEmpty(xmlString))
			{
				return false;
			}
			using MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(xmlString));
			XmlSerializer serializer = new XmlSerializer(typeof(ClientLIMS));
			try
			{
				ClientLIMS ss = (ClientLIMS)serializer.Deserialize(stream);
				Port = ss.Port;
				Type = ss.Type;
				HostIP = ss.HostIP;
				return true;
			}
			catch
			{
				return false;
			}
		}
		catch (Exception)
		{
			return false;
		}
	}

	static ClientLIMS()
	{
		ClientLIMS.Receiveevent = null;
		buffer = new byte[1024];
		_instance = null;
	}
}
